home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Best of Shareware
/
Best of PC Windows Shareware 1.0 - Wayzata Technology (7111) (1993).iso
/
mac
/
DOS
/
TELECOMM
/
PCCP047
/
COMSCRPT.C
< prev
next >
Wrap
Text File
|
1992-08-28
|
23KB
|
895 lines
/* Copyright (C) 1992 Peter Edward Cann, all rights reserved.
* MicroSoft QuickC: >qcl term.c graphics.lib
*/
#include<stdio.h>
#include<bios.h>
#include<dos.h>
#include<fcntl.h>
#include<signal.h>
#include<process.h>
#include"port.h"
#define PROGSIZ 512
struct line
{
char type;
union
{
unsigned char byte;
int number;
struct
{
int retries;
unsigned char label;
unsigned char reg;
}
retry;
struct
{
unsigned char label;
unsigned char string[81];
unsigned char ntokens;
}
l_and_s;
unsigned char string[81];
}
stuff;
}
program[PROGSIZ];
#define MAXNSCANS 32
struct
{
unsigned char index;
unsigned char *str;
unsigned char hitlabel;
}
scans[MAXNSCANS];
int nscans;
#define MAXKEYS 64
struct
{
unsigned char key;
unsigned char label;
}
keys[MAXKEYS];
short int labels[256]; /* Not a #define cause we use unsigned char all over */
unsigned short int rregs[256]; /* Same deal */
quit()
{
cleanup(0);
exit(99);
}
int demonflag;
sendchar(c)
unsigned char c;
{
while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
{
if(kbhit())
if(getch()==24)
demonflag=1;
}
outp(basereg, c);
return(0);
}
int follow;
sleep()
{
long tod, tod1, day;
day=0;
_bios_timeofday(_TIME_GETCLOCK, &tod);
while(1)
{
if(_bios_timeofday(_TIME_GETCLOCK, &tod1))
day=20*60*60*24;
if((tod1+day-tod)>8)
break;
}
}
main(argc, argv)
int argc;
char **argv;
{
FILE *scriptfd;
char c, fpname[256], str[81], *strptr, spawnpath[81];
char comstr[16], speedstr[16], bitsstr[16], *spawnargv[41];
int i, j, proglen, value[8], flag, progcnt, demon, curkey, spawnargc;
long timestamp, tstamp, tstamp1, dayofticksp;
index=follow=0;
printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
if(!strcmp(getenv("REMOTE"), "YES"))
{
printf("You appear to be logged in remotely, judging by the environment\n");
printf("variable REMOTE, so it strikes me as somewhat peculiar that you\n");
printf("want to run COMSCRPT. Are you sure you want to do it? (y or n) --> ");
if(getchar()!='y') /* Note getchar() and not getch()! */
{
printf("I didn't think so!\n");
exit(99);
}
else
printf("OK, you're the boss!");
}
if(argc!=2)
{
printf("USAGE: comscrpt <script file basename>\n");
printf("The environment variable PCCPPATH is used for the script file if set.\n");
exit(1);
}
fpname[0]='\0';
if(getenv("PCCPPATH")==NULL)
sprintf(fpname, "%s.scr", argv[1]);
else
sprintf(fpname, "%s\\%s.scr", getenv("PCCPPATH"), argv[1]);
if((scriptfd=fopen(fpname, "r"))==NULL)
{
printf("Error opening script file %s.\n", fpname);
exit(2);
}
fgets(str, 80, scriptfd);
if(sscanf(str, "%s %s %s", comstr, speedstr, bitsstr)!=3)
{
printf("Can't read init params.\n");
exit(10);
}
comnum=atoi(comstr)-1;
speed=atoi(speedstr);
parity=bitsstr[1];
databits=bitsstr[0];
stopbits=bitsstr[2];
setport();
for(i=0;i<256;++i)
labels[i]=-1;
signal(SIGINT, quit);
readset();
setup();
for(i=0;i<256;++i)
rregs[i]=0;
/* Parse */
printf("Parsing...\n");
flag=0;
for(proglen=0;proglen<PROGSIZ;++proglen)
{
if(fgets(str, 80, scriptfd)==NULL)
{
flag=1;
break;
}
for(i=0;i<80;++i)
if(str[i]=='\n')
{
str[i]='\0';
break;
}
else if(str[i]=='\0')
break;
if(!strlen(str))
proglen--;
else
{
if((str[0]!=';')&&(str[0]!='c')&&(str[0]!='+')&&(str[0]!='-')&&(str[1]!=' '))
{
printf("Missing first delimiting space at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
switch(str[0])
{
case ':':
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of label (:) before statement %d.\n", proglen);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("Label %d out of range.\n", value[0]);
cleanup(0);
exit(11);
}
if(labels[value[0]]!=-1)
{
printf("Label %d duplicated at statement %d.\n", value[0], proglen);
cleanup(0);
exit(11);
}
labels[value[0]]=proglen;
proglen--;
break;
case '*':
program[proglen].type='*';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of * at statement %d.\n", proglen);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("Label out of range in * demon at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.number=value[0];
break;
case 'g':
case 'G':
program[proglen].type='g';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of Goto at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("Label out of range in Goto at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.byte=(unsigned char)value[0];
break;
case 'r':
case 'R':
program[proglen].type='r';
if(sscanf(str, "%*c %d %d %d", &value[0], &value[1], &value[2])!=3)
{
printf("Bad scan of Retry at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("Label out of range in Retry at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[2]<0)||(value[2]>255))
{
printf("Register out of range in Retry at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.retry.label=value[0];
program[proglen].stuff.retry.retries=value[1];
program[proglen].stuff.retry.reg=value[2];
break;
case '0':
program[proglen].type='0';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of Zero Retry (0) at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("reg out of range in Zero Retry (0) at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.byte=value[0];
break;
case 'p':
case 'P':
program[proglen].type='p';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of Process at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.number=value[0];
break;
case '>':
program[proglen].type='>';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of > at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("Label out of range in Look-for (>) at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.l_and_s.label=(unsigned char)value[0];
flag=j=0;
for(i=2;i<80;++i)
{
if(flag)
if(str[i]=='|')
program[proglen].stuff.l_and_s.string[j++]='\r';
else if(str[i]=='`')
{
if(str[++i]<'A')
program[proglen].stuff.l_and_s.string[j]=(str[i]-'0')<<4;
else if(str[i]<'a')
program[proglen].stuff.l_and_s.string[j]=(str[i]-'A'+10)<<4;
else
program[proglen].stuff.l_and_s.string[j]=(str[i]-'a'+10)<<4;
if(str[++i]<'A')
program[proglen].stuff.l_and_s.string[j++]|=str[i]-'0';
else if(str[i]<'a')
program[proglen].stuff.l_and_s.string[j++]|=str[i]-'A'+10;
else
program[proglen].stuff.l_and_s.string[j++]|=str[i]-'a'+10;
}
else
program[proglen].stuff.l_and_s.string[j++]=str[i];
if(str[i]==' ')
flag=1;
if(str[i]=='\0')
break;
}
break;
case '?':
program[proglen].type='?';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of ? at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("Label out of range in ? at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.byte=value[0];
break;
case 'd':
case 'D':
program[proglen].type='d';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of d at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("Label out of range in d at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.byte=value[0];
break;
case '<':
program[proglen].type='<';
j=0;
for(i=2;i<80;++i)
{
if(str[i]=='|')
program[proglen].stuff.string[j++]='\r';
else if(str[i]=='`')
{
if(str[++i]<'A')
program[proglen].stuff.string[j]=(str[i]-'0')<<4;
else if(str[i]<'a')
program[proglen].stuff.string[j]=(str[i]-'A'+10)<<4;
else
program[proglen].stuff.string[j]=(str[i]-'a'+10)<<4;
if(str[++i]<'A')
program[proglen].stuff.string[j++]|=str[i]-'0';
else if(str[i]<'a')
program[proglen].stuff.string[j++]|=str[i]-'A'+10;
else
program[proglen].stuff.string[j++]|=str[i]-'a'+10;
}
else
program[proglen].stuff.string[j++]=str[i];
if(str[i]=='\0')
break;
}
break;
case '!':
program[proglen].type='!';
j=0;
for(i=2;i<80;++i)
{
if(str[i]=='|')
program[proglen].stuff.string[j++]='\n';
else if(str[i]=='~')
program[proglen].stuff.string[j++]='\007';
else
program[proglen].stuff.string[j++]=str[i];
if(str[i]=='\0')
break;
}
break;
case 's':
case 'S':
program[proglen].type='s';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of System (s) at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("Label out of range in System (s) at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.l_and_s.label=value[0];
flag=j=0;
for(i=2;i<80;++i)
{
if(flag)
if(str[i]=='|')
program[proglen].stuff.l_and_s.string[j++]='\r';
else
program[proglen].stuff.l_and_s.string[j++]=str[i];
if(str[i]==' ')
flag=1;
if(str[i]=='\0')
break;
}
break;
case 'X':
case 'x':
program[proglen].type='x';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of Execute (x) at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("Label out of range in Execute (x) at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.l_and_s.label=value[0];
flag=j=0;
program[proglen].stuff.l_and_s.ntokens=0;
for(i=2;i<80;++i)
{
if(flag)
if(str[i]=='|')
program[proglen].stuff.l_and_s.string[j++]='\r';
else if(str[i]==' ')
{
program[proglen].stuff.l_and_s.string[j++]='\0';
program[proglen].stuff.l_and_s.ntokens++;
}
else
program[proglen].stuff.l_and_s.string[j++]=str[i];
if(str[i]==' ')
flag=1;
if(str[i]=='\0')
break;
}
program[proglen].stuff.l_and_s.string[80]='\0';
program[proglen].stuff.l_and_s.ntokens++;
break;
case '+':
program[proglen].type='+';
break;
case '-':
program[proglen].type='-';
break;
case 'w':
case 'W':
program[proglen].type='w';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of Wait (w) at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.number=value[0];
break;
case 'k':
case 'K':
program[proglen].type='k';
if(sscanf(str, "%*c %d %c", &value[0], &c)!=2)
{
printf("Bad scan of Key (k) at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[0]<0)||(value[0]>255))
{
printf("Label out of range in Key at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
program[proglen].stuff.l_and_s.label=(unsigned char)value[0];
if(c=='|')
program[proglen].stuff.l_and_s.string[0]='\r';
else if(c=='`')
{
if(sscanf(str, "%*c %*d %*c%x", &value[0])!=1)
{
printf("Error scanning hex charcode in statement %d. Statement reads:\n%s\n", proglen, str);
}
program[proglen].stuff.l_and_s.string[0]=(unsigned char)value[0];
}
else
program[proglen].stuff.l_and_s.string[0]=(unsigned char)c;
break;
case 'c':
case 'C':
program[proglen].type='c';
case 'q':
case 'Q':
program[proglen].type='q';
if(sscanf(str, "%*c %d", &value[0])!=1)
{
printf("Bad scan of Quit at statement %d.\n", proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(11);
}
if((value[0]<128)&&(value[0]!=0))
{
printf("Quit with reserved exit code (!=0&&<128) at statement %d.\n", proglen);
cleanup(0);
exit(11);
}
program[proglen].stuff.number=value[0];
break;
case ';':
proglen--;
break;
default:
printf("Bad command character %c at statement %d.\n", str[0], proglen);
printf("Statement reads:\n%s\n", str);
cleanup(0);
exit(10);
}
}
}
if(!flag)
{
printf("Program too long.\n");
cleanup(0);
exit(11);
}
/* Check labels */
printf("Checking branch label validity...\n");
for(i=0;i<proglen;i++)
switch(program[i].type)
{
case 'g':
case '?':
case 'd':
if(labels[program[i].stuff.byte]==-1)
{
printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.byte, i, program[i].type);
cleanup(0);
exit(13);
}
break;
case '*':
if((program[i].stuff.number>=0)&&(labels[program[i].stuff.number]==-1))
{
printf("Unlisted label %d at statement %d (*).\n", program[i].stuff.number, i);
cleanup(0);
exit(13);
}
break;
case 'r':
if(labels[program[i].stuff.retry.label]==-1)
{
printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.retry.label, i, program[i].type);
cleanup(0);
exit(13);
}
break;
case '>':
case 'k':
if(labels[program[i].stuff.l_and_s.label]==-1)
{
printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.l_and_s.label, i, program[i].type);
cleanup(0);
exit(13);
}
break;
case 'x':
case 's':
if(labels[program[i].stuff.l_and_s.label]==-1)
{
printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.l_and_s.label, i, program[i].type);
cleanup(0);
exit(13);
}
break;
}
printf("Executing...\n");
/* Execute */
progcnt=nscans=curkey=0;
demonflag=0;
demon=-1;
while(1)
{
if(kbhit())
if(getch()==24)
if(demon>=0)
progcnt=demon;
if(demonflag)
{
demonflag=0;
if(demon>=0)
progcnt=demon;
}
if(progcnt>=proglen)
{
printf("\nFell through end of program.\n");
cleanup(0);
exit(100);
}
switch(program[progcnt].type)
{
case 'g':
progcnt=labels[program[progcnt].stuff.byte];
break;
case '*':
if(program[progcnt].stuff.number>=0)
demon=labels[program[progcnt].stuff.number];
else
demon=-1;
progcnt++;
break;
case 'r':
if(++rregs[program[progcnt].stuff.retry.reg]>=program[progcnt].stuff.retry.retries)
{
rregs[program[progcnt].stuff.retry.reg]=0;
progcnt=labels[program[progcnt].stuff.retry.label];
}
else
progcnt++;
break;
case '0':
rregs[program[progcnt].stuff.byte]=0;
progcnt++;
break;
case 'p':
timestamp=time(NULL);
flag=1;
while(flag)
{
while(1)
{
if(program[progcnt].stuff.number&&((time(NULL)-timestamp)>program[progcnt].stuff.number))
{
progcnt++;
flag=0;
break;
}
if(follow!=index)
{
putch(c=buf[follow++]);
follow%=TBUFSIZ;
if((c&0x7f)!='\n')
break;
}
if(kbhit())
if(getch()==24)
{
demonflag=1;
flag=0;
break;
}
}
if(!flag)
break;
for(i=0;i<nscans;++i)
if((scans[i].str[scans[i].index]&0x7f)==(c&0x7f))
if(scans[i].str[++scans[i].index]=='\0')
{
if(labels[scans[i].hitlabel]==-1)
{
printf("\nGoto unlisted label %d at statement %d.\n", scans[i].hitlabel, progcnt);
cleanup(0);
exit(12);
}
progcnt=labels[scans[i].hitlabel];
flag=0;
break;
}
else;
else
scans[i].index=0;
}
nscans=0;
break;
case '>':
if(nscans>=MAXNSCANS)
{
printf("Too many lookfors (>).\n");
progcnt++;
break;
}
scans[nscans].index=0;
scans[nscans].str=program[progcnt].stuff.l_and_s.string;
scans[nscans++].hitlabel=program[progcnt].stuff.l_and_s.label;
progcnt++;
break;
case '?':
if(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
progcnt=labels[program[progcnt].stuff.byte];
else
progcnt++;
break;
case 'd':
if(inp(basereg+MSTATREG)&DCDMASK)
progcnt=labels[program[progcnt].stuff.byte];
else
progcnt++;
break;
case '<':
for(i=0;i<80;i++)
if(program[progcnt].stuff.string[i]=='\0')
break;
else if(program[progcnt].stuff.string[i]=='~')
sleep();
else if(program[progcnt].stuff.string[i]=='^')
{
_bios_timeofday(_TIME_GETCLOCK, &tstamp);
outp(basereg+LCTLREG, lctl|0x40);
dayofticksp=0;
while(1)
{
if(_bios_timeofday(_TIME_GETCLOCK, &tstamp1))
dayofticksp+=20*60*60*24;
if(tstamp1+dayofticksp-tstamp>10)
break;
}
outp(basereg+LCTLREG, lctl);
}
else
sendchar(program[progcnt].stuff.string[i]);
progcnt++;
break;
case '!':
printf("%s", program[progcnt].stuff.string);
progcnt++;
break;
case 's':
printf("\n");
cleanup(INHCTL);
if(system(program[progcnt].stuff.l_and_s.string)==-1)
{
progcnt=labels[program[progcnt].stuff.l_and_s.label];
}
else
progcnt++;
setup();
printf("\nBack to script.\n");
break;
case 'x':
printf("\n");
cleanup(INHCTL);
spawnargc=0;
if(program[progcnt].stuff.l_and_s.string[0]!='\0')
{
spawnargv[spawnargc++]=&program[progcnt].stuff.l_and_s.string[0];
for(j=0,i=1;i<program[progcnt].stuff.l_and_s.ntokens;i++)
{
while(program[progcnt].stuff.l_and_s.string[j++]!='\0');
spawnargv[spawnargc++]=&program[progcnt].stuff.l_and_s.string[j];
}
spawnargv[spawnargc++]=NULL;
strcpy(spawnpath, spawnargv[0]);
if(value[0]=spawnvp(P_WAIT, spawnpath, spawnargv))
{
progcnt=labels[program[progcnt].stuff.l_and_s.label];
}
else
progcnt++;
}
else
progcnt++;
setup();
printf("\nExit code = %d. Back to script.\n", value[0]);
break;
case '+':
outp(basereg+MCTLREG, 0x0b);
progcnt++;
break;
case '-':
outp(basereg+MCTLREG, 0x0a);
progcnt++;
break;
case 'k':
if(curkey>=MAXKEYS)
{
printf("Excess key daemon ignored.\n");
progcnt++;
break;
}
keys[curkey].key=program[progcnt].stuff.l_and_s.string[0];
keys[curkey++].label=program[progcnt].stuff.l_and_s.label;
progcnt++;
break;
case 'w':
timestamp=time(NULL);
while(1)
{
if(program[progcnt].stuff.number&&((time(NULL)-timestamp)>program[progcnt].stuff.number))
{
printf("\nKeyboard entry timeout.\n");
progcnt++;
break;
}
if(kbhit())
{
c=getch();
if(c==24)
if(demon>=0)
{
progcnt=demon;
break;
}
for(i=0;i<curkey;i++)
if(c==keys[i].key)
{
progcnt=labels[keys[i].label];
break;
}
if(i>=curkey)
printf("\n\007Non-programmed key! (%c) Re-enter: -->", c);
else
break;
}
}
curkey=0;
break;
case 'c':
curkey=nscans=0;
progcnt++;
break;
case 'q':
cleanup(0);
exit(program[progcnt].stuff.number);
}
}
}